export default {
  defalutPage: '',//启动页的名字 不带后缀
  isUserJump: false, //用于路由地址切换时 忽略页面点击的页面跳转路由监控    
  hasTitle: false, //判断每个页面是否设置了title，如果没有则默认给与文件名
  pageBox: document.createElement("div"), //HTML容器元素
  elemStyle: document.createElement("style"), //style元素，放置每个单页的混合样式
  elemTitle: null,
  elemJs: null,//script元素
  query: null,//loadPage的传值 暂存
  distance: 0, //防拖动和点击事件冲突的判断 从点击后拖动的距离

  setTitle(str) {
    this.hasTitle = true;
    let elem: HTMLInputElement = document.querySelector('head title') as HTMLInputElement
    elem.innerHTML = str
  },
  init(pagename) {
    //pagename 初始化指定首页
    if (pagename) {
      this.defalutPage = this.getFilename(pagename)
    }

    //主页底板样式
    let styleE = document.createElement("style")
    styleE.innerHTML = `    
      #AcityLoaderPagebox {
        position: absolute;
        width: 100vw;
        height: 100vh;
        top: 0;
        left: 0;
        z-index: 1;
      }`
    document.head.append(styleE)

    this.elemStyle.id = 'AcityLoaderCss'
    document.head.append(this.elemStyle)

    this.pageBox.id = 'AcityLoaderPagebox'
    document.body.append(this.pageBox)

    //全局事件加载
    this.addWindowEvent()
  },
  loadEnd(query) {
    //窗口之间的传值可用这个函数
  },
  loadPage(url = '', queryStr) {
    if (/http/.test(url)) {
      window.location.href = url
      return
    }
    this.query = queryStr
    //加载HTML CSS和JS
    this.getHtml(url)
  },
  getHtml(url) {
    this.ajaxPromise({
      type: 'get',
      url: url,
    }).then(date => {

      //以下重置等内容必须页面加载正常后执行 --------------------------
      //暂存传值，当loadend后，返回    


      //通知路由地址监控，说明是用户界面内操作加载，而非地址修改加载
      this.isUserJump = true

      this.elemStyle.innerHTML = ""
      if (this.elemJs !== null) {
        //清空页面自带的默认JS
        let elem: HTMLInputElement = document.getElementById('loadjs') as HTMLInputElement
        elem.remove()
        this.elemJs = null
      }
      //删除之前加载的插件
      document.querySelectorAll('script[name=plugins]').forEach(elem => {
        elem.remove();
      })
      //以上重置等内容必须页面加载正常后执行 --------------------------

      //********* */
      this.hasTitle = false;
      let htmlStr = date
      let fileName = this.getFilename(url)

      class MyRegExp extends RegExp {
        [Symbol.matchAll](str) {
          const result = RegExp.prototype[Symbol.matchAll].call(this, str);
          if (!result) {
            return null;
          } else {
            return Array.from(result);
          }
        }
      }

      const reg = new MyRegExp('<link[^>]*href=(\"|\'| )*[^>]*>', 'g')
      let result = htmlStr.matchAll(reg)

      result.forEach(item => {
        let a = item[0].replace(/<link|rel=(\"|\'| )[a-z]*(\"|\'| )|href=(\"|\'| )|(\"|\'| )*|[^>]*>/g, '')
      })

      this.getCss(fileName, () => {
        //html加载
        this.pageBox.innerHTML = this.filterHtmlStr(htmlStr)
      })
    })
  },
  getCss(filename, htmlLoad) {


    let cssName = `css/${filename}.css`
    this.ajaxPromise({
      type: 'get',
      url: cssName,
    }).then(date => {
      //调整图片路径
      this.elemStyle.innerHTML = date.replace(/(\.\.\/)*(\.\.\/)/g, '')
      //CSS加载完毕后加载HTML
      htmlLoad()

      //js加载
      this.elemJs = document.createElement("script")
      this.elemJs.id = 'loadjs'

      this.elemJs.src = `js/${filename}.js`
      document.body.append(this.elemJs)

      this.elemJs.onload = () => {
        //调整地址路由
        window.location.href = `#/${filename}`
        //地址调整并非单线程顺序执行！
        setTimeout(() => {
          this.isUserJump = false
        }, 1)

        //这个方法是约定给子页面获取的，每个子页面如果重新声明该方法则可以得到上一页面的传值 ，todo 如果是多次加载的话，必须在最后一个JS加载完毕后执行
        this.loadEnd(this.query)
        //
        if (!this.hasTitle) {
          this.setTitle(filename)
        }
      }

    })
  },
  //加载额外的JS插件
  getPlugin(url, callback = new Function()) {
    let filename = this.getFilename(url)

    let elemScript = document.createElement("script")

    elemScript.id = filename
    elemScript.setAttribute('name', 'plugins')
    elemScript.src = `js/${filename}.js`
    elemScript.onload = () => {
      callback()
    }
    document.body.append(elemScript)

  },
  //针对JS加载异常的超时管理，超时后将删除JS 或 JS插件注册表
  rollback(e) {
    console.log('删除无法加载的插件JS标签')
    e.srcElement.remove()
    //var result = [];
    // 获取当前页面所有请求对应的PerformanceResourceTiming对象进行分析
    // window.performance.getEntries().forEach(item => {
    //   result.push(item);
    // });
  },
  filterHtmlStr(str) {
    let strIdx = str.indexOf('<body>') + 6
    let endIdx = str.indexOf('</body>')
    return str.substring(strIdx, endIdx)
  },
  getFilename(str) {
    let reg = /.*\/([^\.\/]+)/g;
    let filename = str.replace(reg, "$1");
    return filename.replace(/.html|.js|.css/, "")
  },
  //异步
  ajaxPromise(param = {
    type: '',
    url: '',
    data: {},
    isJson: false,
  }) {
    return new Promise((resovle, reject) => {
      var xhr = new XMLHttpRequest();

      xhr.open(param.type || "get", param.url, true);
      //xhr.setRequestHeader("Content-type", "multipart/form-data");
      if (param.isJson) {
        xhr.setRequestHeader("Content-type", "application/json");
      }
      xhr.send(param.data || null);
      // contentType: false,   //必须设置为false
      // processData: false,   //必须设置为false
      xhr.onreadystatechange = () => {
        var DONE = 4; // readyState 4 代表已向服务器发送请求
        var OK = 200; // status 200 代表服务器返回成功
        if (xhr.readyState === DONE) {
          if (xhr.status === OK) {
            if (param.isJson) {
              resovle(JSON.parse(xhr.responseText));
            } else {
              resovle(xhr.responseText);
            }

          } else {
            if (param.isJson) {
              reject(JSON.parse(xhr.responseText));
            } else {
              reject(xhr.responseText);
            }
          }
        }
      }


      xhr.onerror = () => {
        console.log(111)
      }
    })
  },
  /**
   * 
   * @param {string} selStr 选择器字符串
   * @param {string} eventType 目前仅支持'touch' todo:将来还包括支持'drag'拖动和'dtouch'双击
   * @param {function} callback 回调，一般返回参数是所选DOM，如果将来的滑动 还会返回更多信息
   */
  addEvent(selStr = '', eventType = '', callback = new Function) {
    let that = this
    document.querySelectorAll(selStr).forEach(elem => {
      elem.addEventListener(eventType, e => {
        callback(e, that.distance)
      })
    })
  },

  addWindowEvent() {
    //加载
    window.addEventListener("load", e => {

      let filename = location.href.replace(/.*\//g, '')
      //为了地址简洁，将处理掉/index.html显示的地址内容
      if (filename === 'index.html') {
        window.location.href = location.href.replace(/index.html/g, '')
      }
      //首页加载
      if (this.defalutPage !== '') {
        filename = this.defalutPage
      }
      this.loadPage(`${filename}.html`)
    })
    //路由监听
    window.addEventListener(
      "hashchange",
      e => {
        if (!this.isUserJump) {
          let filename = e.newURL.replace(/.*\//g, '')
          this.loadPage(`${filename}.html`)
        }
      })
    //捕获网络请求错误
    window.addEventListener(
      "error",
      e => {
        e.stopImmediatePropagation();
        const srcElement: HTMLInputElement = e.target as HTMLInputElement;;

        if (e.target === window) {
          // 全局错误
          console.log("全局错误");
          console.log("message", e.message);
        } else if (srcElement.name === 'plugins') {
          if (this) {
            this.rollback(e)
          }
        } else {
          // 元素错误，比如引用资源报错
          console.log("元素错误");
          console.log("tagname", srcElement.tagName);
          console.log("src", srcElement.src);
        }
        console.log("onerror捕获网络请求错误", e); // 捕获错误
      },
      true //网络错误，在捕获阶段获取，第三个参数为true
    )
  }
}





//window事件加载-----------------------------------------------

//判断移动设备和桌面设备 
// {
//   let inX, inY, outX, outY, dx, dy, eventStart, eventMove, eventEnd
//   if (document.hasOwnProperty("ontouchstart")) {
//     eventStart = 'touchstart', eventMove = 'touchmove', eventEnd = 'touchend'
//   } else {
//     eventStart = 'mousedown', eventMove = 'mousemove', eventEnd = 'mouseup'
//   }

//   document.addEventListener(eventStart, e => {
//     console.log('bb')
//     inX = e.pageX, inY = e.pageY
//     AcityLoader.distance = 0
//   })
//   document.addEventListener(eventMove, e => {
//     outX = e.pageX, outY = e.pageY
//   })
//   document.addEventListener(eventEnd, e => {
//     //勾股取距离
//     dx = Math.abs(outX - inX)
//     dy = Math.abs(outY - inY)
//     AcityLoader.distance = Math.sqrt(dx * dx + dy * dy);

//     console.log("distanceA:",AcityLoader.distance)
//   })
// }



